package com.invengo.module_robot.ui.fragment.search;

import android.annotation.SuppressLint;
import android.app.Application;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.databinding.ObservableArrayList;
import androidx.databinding.ObservableList;

import com.invengo.base.http.RobotBaseBean;
import com.invengo.base.http.RobotRxUtils;
import com.invengo.library_orionstar.ActionEvent;
import com.invengo.library_orionstar.SpeechEvent;
import com.invengo.module_robot.BR;
import com.invengo.module_robot.R;
import com.invengo.module_robot.data.entity.ConfigBean;
import com.invengo.module_robot.data.entity.DouBanBeans;
import com.invengo.module_robot.data.entity.PopularBean;
import com.invengo.module_robot.data.entity.SearchBean;
import com.invengo.module_robot.data.entity.TempBookBean;
import com.invengo.module_robot.data.repsitory.RobotRepsitory;
import com.invengo.module_robot.ui.fragment.search.item.SearchItemViewModel;

import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function;
import io.reactivex.schedulers.Schedulers;
import me.goldze.mvvmhabit.base.BaseViewModel;
import me.goldze.mvvmhabit.binding.command.BindingCommand;
import me.goldze.mvvmhabit.bus.Messenger;
import me.goldze.mvvmhabit.bus.event.SingleLiveEvent;
import me.goldze.mvvmhabit.utils.KLog;
import me.goldze.mvvmhabit.utils.RxUtils;
import me.goldze.mvvmhabit.utils.ToastUtils;
import me.goldze.mvvmhabit.utils.cache.ACache;
import me.goldze.mvvmhabit.utils.cache.AKey;
import me.jessyan.retrofiturlmanager.RetrofitUrlManager;
import me.tatarka.bindingcollectionadapter2.ItemBinding;
import okhttp3.HttpUrl;

public class SearchViewModel extends BaseViewModel<RobotRepsitory> {

    private int currentPosition = 0;
    private int moveSize = 6;

    private boolean isMove2Buttom = false;
    public SingleLiveEvent<Boolean> enableLoadMore = new SingleLiveEvent<>();
    public SingleLiveEvent<Boolean> showRecommend = new SingleLiveEvent<>();
    public SingleLiveEvent<String> bookName = new SingleLiveEvent<>();
    public SingleLiveEvent<String> tipContent = new SingleLiveEvent<>();
    public ObservableList<SearchItemViewModel> bookItemList = new ObservableArrayList<>();
    public ItemBinding<SearchItemViewModel> bookitemBinding = ItemBinding.of(BR.viewModel, R.layout.item_search_book);

    public SearchViewModel(@NonNull Application application) {
        super(application, RobotRepsitory.getInstance());
        showRecommend.postValue(false);
        enableLoadMore.postValue(true);
        bookName.postValue("");
    }

    /**
     * 流行豆子
     */
    private List<PopularBean> popularBeans = new ArrayList<>();

    /**
     * 获取受欢迎豆子
     */
    public void getPopularBeans() {
        popularBeans.clear();
        model.getPopularBook()
                .compose(RobotRxUtils.applySchedulers(getLifecycleProvider(), this, false))
                .subscribe(beans -> {
                    popularBeans.addAll(beans);
                });
    }


    public UIChangeObservable ui = new UIChangeObservable();

    /**
     * 设置当前位置
     *
     * @param mFirstVisiblePosition m第一个可见位置
     */
    public void setCurrentPosition(int mFirstVisiblePosition) {
        this.currentPosition = mFirstVisiblePosition;
    }

    /**
     * 设置move2按钮
     *
     * @param canScrollVertically 可以垂直滚动
     */
    public void setMove2Buttom(boolean canScrollVertically) {
        isMove2Buttom = canScrollVertically;
    }

    /**
     * 保存配置
     *
     * @param host     主办
     * @param userName 用户名
     * @param passWord 口令
     */
    public void saveConfig(String host, String userName, String passWord,String tenantId) {
        KLog.e(ACache.getInstance().getAsString(AKey.CACHE_HOST));
        KLog.e(host.equals(ACache.getInstance().getAsString(AKey.CACHE_HOST)));
        KLog.e(ACache.getInstance().getAsString(AKey.ROBOT_TENANT_ID)+ tenantId);
//        if (host.equals(ACache.getInstance().getAsString(AKey.CACHE_HOST))) {
//            finish();
//            return;
//        }
        if (TextUtils.isEmpty(host)) {
            ToastUtils.showShort("API地址不能为空!");
            return;
        }
        HttpUrl parse = HttpUrl.parse(host);
        if (parse == null) {
            ToastUtils.showShort("请输入正确的地址!");
            return;
        }

        ConfigBean bean = new ConfigBean(host, userName, passWord,tenantId);
        model.saveConfig(bean);
        ACache.getInstance().put(AKey.CACHE_HOST, host);
        RetrofitUrlManager.getInstance().setGlobalDomain(host);
        KLog.e("更改后的id： "+ACache.getInstance().getAsString(AKey.ROBOT_TENANT_ID));
    }

    public class UIChangeObservable {
        public SingleLiveEvent<Integer> moveEvent = new SingleLiveEvent<>();
        public SingleLiveEvent<ConfigBean> userConfigEvent = new SingleLiveEvent<>();
        public SingleLiveEvent<Object> launchBookInfo = new SingleLiveEvent<>();
        public SingleLiveEvent<TempBookBean> itemEvent = new SingleLiveEvent<>();
    }

    /**
     * 启动信息
     *
     * @param bean 豆
     */
    public void launchInfo(TempBookBean bean) {
        ui.itemEvent.postValue(bean);
    }

    /**
     * 启动起始命令
     */
    public BindingCommand launchHomeCommand = new BindingCommand(() -> {
        Messenger.getDefault().send(ActionEvent.opBack(), "OPEARTION_TO_PAGE");
    });
    private String tempValue = "";
    /**
     * 论搜索命令
     */
    public BindingCommand onSearchCommand = new BindingCommand(() -> {
        getUC().getHideKeyboardEvent().call();
        if (tempValue.equals(bookName.getValue()) | TextUtils.isEmpty(bookName.getValue())) {
            KLog.e("内容一样或者数据是null的");
        } else {
            this.tempValue = bookName.getValue();
            KLog.e("查询内容: " + bookName.getValue());
            searchBooks(bookName.getValue());
        }
    });

    /**
     * search命令
     */
    public BindingCommand<String> searchCommand = new BindingCommand<>(question -> {
        Observable.just(question)
                .subscribeOn(AndroidSchedulers.mainThread())
                .subscribe(s -> {
                    bookName.postValue(question);
                    searchList(question);
                });
    });

    /**
     * 设置用户配置
     */
    public BindingCommand setUserConfig = new BindingCommand(() -> {
        ConfigBean bean = (ConfigBean) ACache.getInstance().getAsObject(AKey.ROBOT_CONFIG);
        if (bean == null) {
            bean = new ConfigBean(ACache.getInstance().getAsString(AKey.CACHE_HOST), "admin", "123qwe","7795");
        }
        ui.userConfigEvent.postValue(bean);
    });

    /**
     * 搜索列表
     *
     * @param keyWord 关键词
     */
    @SuppressLint("NewApi")
    private void searchList(String keyWord) {
        Optional<SearchItemViewModel> first = bookItemList.stream().filter(b -> b.bookName.getValue().equals(keyWord))
                .findFirst();
        if (first.isPresent()) {
            Messenger.getDefault().send(SpeechEvent.answer("好的！"), "SPEECH_TO_PAGE");
            ui.itemEvent.postValue(first.get().getBookBean());
        } else {
            bookItemList.clear();
            searchBooks(keyWord);
        }
    }

    /**
     * 搜索书籍
     *
     * @param keyWord 关键词
     */
    private void searchBooks(String keyWord) {
        long start = System.currentTimeMillis();
        getUC().getShowRobotLoadingEvent().call();
        model.searchBooks(keyWord)
                .subscribeOn(Schedulers.io())
                .compose(RxUtils.bindToLifecycle(getLifecycleProvider()))
                .map(new RobotRxUtils.HandleFuc<>())
                .flatMap((Function<SearchBean, ObservableSource<List<TempBookBean>>>) searchBean -> {
                    boolean haveData = searchBean.getTotalCount() != 0;
                    showRecommend.postValue(!haveData);
                    List<TempBookBean> beans = new ArrayList<>();
                    List<String> isbns = new ArrayList<>();
                    for (SearchBean.OneItemsDTO item : searchBean.getItems()) {
                        TempBookBean bean = new TempBookBean();
                        bean.analyzeSearchBean(item);
                        isbns.add(item.getBookInfo().getIsbn());
                        beans.add(bean);
                    }
                    if (!isbns.isEmpty()) {
                        long start22 = System.currentTimeMillis();
                        KLog.e(isbns);
                        RobotBaseBean<List<DouBanBeans>> listRobotBaseBean = model.getImages(isbns)
                                .subscribeOn(Schedulers.io())
//                                .map(new RobotRxUtils.HandleFuc<>())
                                .blockingSingle();
                        KLog.e("查到数据获取图片时间： " + (System.currentTimeMillis() - start22));
                        if (listRobotBaseBean.isSuccess() && listRobotBaseBean.getResult() != null) {
                            List<DouBanBeans> douBanBeans = listRobotBaseBean.getResult();
                            for (int i = 0; i < douBanBeans.size(); i++) {
                                beans.get(i).setImage(douBanBeans.get(i).getImage());
                                beans.get(i).setRemark(douBanBeans.get(i).getSummary());
                            }
                        }
                    } else {
                        tipContent.postValue(haveData ? "为您找到以下书籍" : "没有找到你要找到书，为你推荐热门图书");
                        if (popularBeans.isEmpty()) {
                            long start11 = System.currentTimeMillis();
                            popularBeans = model.getPopularBook().map(new RobotRxUtils.HandleFuc<>()).blockingSingle();
                            KLog.e("获取推荐图书时间： " + (System.currentTimeMillis() - start11));
                        }
                        pageSize = 0;
                    }
                    return haveData ? Observable.just(beans) : Observable.just(popularTran2TempBean());
                })
                .observeOn(AndroidSchedulers.mainThread())
                .doFinally(() -> {
                    getUC().getHideRobotLoadingEvent().call();
                })
                .subscribe(tempBookBeans -> {
                    bookItemList.clear();
                    KLog.e("查询接口时间： " + (System.currentTimeMillis() - start));
                    for (TempBookBean tempBookBean : tempBookBeans) {
                        bookItemList.add(new SearchItemViewModel(SearchViewModel.this, tempBookBean));
                    }
                }, throwable -> {
                    if (throwable instanceof SocketException|throwable instanceof SocketTimeoutException) {
                        ToastUtils.showShort("网络异常超时。。。");
                    }else{
                        ToastUtils.showShort(throwable.getMessage()+" ");
                    }
                });
    }

    private int pageSize = 0;

    /**
     * 流行tran2 temp bean
     *
     * @return {@link List}<{@link TempBookBean}>
     */
    private List<TempBookBean> popularTran2TempBean() {
        List<TempBookBean> beans = new ArrayList<>();
        bookItemList.clear();
        for (int i = 0; i < popularBeans.size(); i++) {
            if (i >= pageSize * 18 && i < (pageSize + 1) * 18) {
                TempBookBean bean = new TempBookBean();
                bean.analyzePopularBook(popularBeans.get(i));
                beans.add(bean);
            }
        }
        return beans;
    }


    public BindingCommand launchMain = new BindingCommand(() -> {
        getUC().getFinishActivityEvent().call();
    });

    /**
     * move2 next
     */
    private void move2Next() {    //移动到下一页
        ui.moveEvent.postValue(currentPosition + moveSize);
    }

    /**
     * move2 pre
     */
    private void move2Pre() {    //移动到上一页
        ui.moveEvent.postValue(currentPosition - moveSize <= 0 ? 0 : (isMove2Buttom ? currentPosition : currentPosition - moveSize));
    }

    /**
     * 动作命令
     */
    public BindingCommand<ActionEvent> actionCommand = new BindingCommand<>(action -> {
        Observable.just(action)
                .subscribeOn(AndroidSchedulers.mainThread())
                .subscribe(event -> {
                    switch (action.getEvent()) {
                        case ActionEvent.ACTION_DOWN:
                            move2Next();
                            break;
                        case ActionEvent.ACTION_UP:
                            move2Pre();
                            break;
                        case ActionEvent.ACTION_MOVE_TOP:
                            if (bookItemList.size() > 0)
                                ui.moveEvent.postValue(0);
                            break;
                        case ActionEvent.ACTION_MOVE_BUTTOM:
                            if (bookItemList.size() > 0)
                                ui.moveEvent.postValue(bookItemList.size() - 1);
                            break;
                        case ActionEvent.ACTION_CHANGE:
                            changeBook();
                            break;
                    }
                });
    });
    /**
     * 零钱簿
     */
    public BindingCommand changeBook = new BindingCommand(() -> {
        changeBook();
    });

    /**
     * 零钱簿
     */
    private void changeBook() {
        pageSize++;
        if (pageSize >= (popularBeans.size() % 18 == 0 ? popularBeans.size() / 18 : popularBeans.size() / 18 + 1))
            pageSize = 0;
        List<TempBookBean> beans = popularTran2TempBean();
        for (TempBookBean bean : beans) {
            bookItemList.add(new SearchItemViewModel(this, bean));
        }
    }

}
